home *** CD-ROM | disk | FTP | other *** search
- ARM BBC BASIC V: changes between 1.02 and 1.04
-
- (1) OVERLAY
-
- OVERLAY allows a single set of programs (referred to by a pre-initialised
- string array) to be loaded into common memory. The LVAR command lists the
- first line of libraries or installed libraries; the order of listing is also
- the order of searching - which is simply (a) search current program (b)
- search any LIBRARYs, last mentioned first (the order shown by LVAR) (c)
- search any INSTALLed libraries, again last mentioned first (d) search the
- OVERLAY library, starting with the current overlay in core (if there is one)
- and then linearly from the start of the OVERLAY array.
-
- The OVERLAY statement takes a string array and allocates a single block of
- store large enough to hold any single one of the programs: at this stage no
- program is actually loaded. The programs referred to in the string array will
- be searched for procedure and functions and, once this has been found, the
- interpreter will load in the right overlay in order to execute it. One cannot
- call items in other overlays from an overlay library (even implicitly via the
- main program or other libraries). The search time can be reduced by setting
- the approriate element of the array to a null string when that library no
- longer needs to be consulted. It is important not to confuse the interpreter
- by changing the names in the string array! Another OVERLAY statement will
- work (after forgetting all the referenced procedures) but the store used by
- the first one will be lost: however, one can add new strings to the existing
- array provided the programs referred to are no larger than the largest one
- given to the OVERLAY statement.
-
- DIM A$(10)
- A$(1)="adfs:&.Assistant":A$(2)="net:$.Matrices":A$(3)="net:$.PlotLib"
- OVERLAY A$()
-
- (2) Save and restore DATA pointer (onto the stack)
-
- Since DATA statements can be used in procedure libraries (by using RESTORE
- +), transparent use of the DATA pointer is also provided. The current value
- can be saved onto the stack just like the error status.
-
- LOCAL DATA (may be used anywhere, unlike LOCAL A etc)
- Makes the use of DATA local; i.e. saves the DATA pointer on the stack.
-
- RESTORE DATA
- Restore DATA pointer from the stack. An error will occur if the next
- thing on the stack is not a DATA pointer.
-
- Returning from a function or procedure will restore any DATA pointer it
- finds on the stack. LOCAL DATA must be the last thing to be made local in a
- procedure or function (apart from LOCAL ERROR).
-
- REM "safe" routine for reading in an array
- DEF PROCRead(A())
- REM going to use local DATA so save status
- LOCAL DATA
- REM set pointer
- RESTORE +0
- DATA 1,2,3,4,5,6,7,&99
- REM do the job!
- ENDPROC
- REM end of procedure will restore error status
-
- (3) Array initialisation
-
- A$()=<factor>,<expression>,<expression> ..
- A%()=<factor>,<expression>,<expression> ..
- A()=<factor>,<expression>,<expression> ..
-
- Array initialisation can be done with all elements that same (A()=1) or with
- element by element initialisation (A()=1,2,3,4,5,6 etc.). The element by
- element form will leave any unspecified values alone. The order of values
- given in the list is "last subscript changes quickest" i.e. for DIM A(2,1),
- they would be A(0,0); A(0,1); A(1,0); A(1,1); A(2,0); A(2,1) in order.
-
- (4) SUMLEN
-
- SUMLEN which returns the sum of the lengths of all the strings in a string
- array.
-
- (5) MOD
-
- MOD which returns the modulus (square root of the sum of the squares of each
- element) of a numeric array.
-
- Example of (3), (4) and (5):
-
- transformation()=1,0,0,0,1,0,0,0,1
- coordinate()=coordinate().transformation()
- PRINT"There are ";SUMLEN(A$())" characters."
- normalisedvector()=vector()/MODvector()
-
- (6) ERROR EXT
-
- ERROR EXT <number>,<string> passes an error to the caller's error handler
-
- (7) QUIT
-
- QUIT function: TRUE if BASIC has been called with -quit on command line
-
- (8) Store allocation
-
- When a string is stored, the current space is immediately used if the number
- of words is compatible; otherwise the space is deallocated: it is stored on
- the appropriate member of an array of free lists, each list having one size
- in words. This makes allocation of the new space for a string very quick:
- check the free list corresponding to the desired length, if there is an
- entry, take it; otherwise use new space. Use of contiguous store has been
- disabled in 1.03 since it gives rise to some strange side effects: programs
- running on 1.03 may use fractionally more store than on 1.02, but generally
- long term use of strings will result in less used memory.
-
- (9) Revised error descriptions
-
- 0,"Silly!"
- 0,"No room to do this renumber"
- 0,"Line numbers larger than 65279 would be generated by this renumber"
- 0,"No room"
- 0,"Line too long"
- 0,"Stopped"
- 0,"Invalid LISTO option"
- 0,"Invalid TWINO option"
- 0,"Corruption of stack"
- 0,"Error control status not found on stack for RESTORE ERROR"
- 0,"Missing incore name"
- 0,"LIST/TWIN found line number reference"
- 0,"HELP has no information on this keyword"
- 0,"Incorrect in-core file description"
- 1,"No such mnemonic"
- 1,"No such suffix on EQU"
- 2,"Bad immediate constant"
- 2,"Bad address offset"
- 2,"Assembler limit reached"
- 2,"Bad shift"
- 3,"Bad register"
- 3,"Duplicate register in multiply"
- 4,"Missing ="
- 4,"Missing = in FOR statement"
- 4,"Mistake"
- 5,"Missing ,"
- 6,"Type mismatch: number needed"
- 6,"Type mismatch: numeric variable needed"
- 6,"Type mismatch: numeric array needed"
- 6,"Type mismatch: string needed"
- 6,"Type mismatch: string variable needed"
- 6,"Type mismatch: string array needed"
- 6,"Type mismatch: array needed"
- 6,"Type mismatch between arrays"
- 6,"Can't assign to array of this size"
- 6,"Array type mismatch as parameter"
- 6,"Can't SWAP arrays of different types"
- 7,"Not in a function"
- 8,"Too low a value for $<number>"
- 9,"Missing """
- 10,"DIM() function needs an array"
- 10,"No room to do matrix multiply with source(s) the same as destination"
- 10,"Impossible dimension"
- 10,"No end of dimension list )"
- 10,"Bad DIM statement"
- 10,"Can't DIM negative amount"
- 10,"Arrays cannot be redimensioned"
- 11,"No room for this DIM"
- 11,"No room for this dimension"
- 11,"Attempt to allocate insufficient memory"
- 12,"Items can only be made local in a function or procedure"
- 13,"Not in a procedure"
- 14,"Reference array incorrect"
- 14,"Unknown array"
- 14,"Unknown array in DIM() function"
- 14,"Undimensioned array"
- 15,"Subscript out of range"
- 15,"Incorrect number of subscripts"
- 16,"Syntax error"
- 17,"Escape"
- 18,"Division by zero"
- 19,"String too long"
- 20,"Number too big"
- 20,"Number too big for arc Sine or arc Cosine"
- 21,"Negative root"
- 22,"Logarithm range"
- 23,"Accuracy lost in Sine/Cosine/Tangent"
- 24,"Exponent range"
- 26,"Unknown or missing variable"
- 26,"Can't use array reference here"
- 27,"Missing )"
- 27,"Missing ("
- 27,"Missing ]"
- 27,"Missing {"
- 27,"Missing }"
- 28,"Bad Hex"
- 28,"Hex number too large"
- 28,"Bad Binary"
- 29,"No such function/procedure"
- 30,"Bad call of function/procedure"
- 31,"Arguments of function/procedure incorrect"
- 31,"Invalid RETURN actual parameter"
- 31,"Invalid array actual parameter"
- 32,"Not in a FOR loop"
- 33,"Can't match FOR"
- 34,"Bad FOR control variable"
- 35,"The step cannot be zero"
- 36,"Missing TO"
- 37,"No room for function/procedure call"
- 38,"Not in a subroutine"
- 39,"ON syntax"
- 40,"ON range"
- 41,"No such line"
- 42,"Out of data"
- 42,"DATA pointer not found on stack for RESTORE DATA"
- 43,"Not in a REPEAT loop"
- 44,"Too many nested structures"
- 45,"Missing #"
- 46,"Not in a WHILE loop"
- 47,"Missing ENDCASE"
- 48,"OF missing from CASE statement"
- 48,"CASE..OF statement must be the last thing on a line"
- 49,"Missing ENDIF"
- 50,"Bad MOUSE variable"
- 51,"Too many input expressions for SYS"
- 51,"Too many output variables for SYS"
- 52,"Can't install library"
- 52,"Bad program used as function/procedure library"
- 52,"No room for library"
-
- (10) New assembler feature
-
- Bit 3 in OPT (opts 8-15) controls an assembler area limit check: the
- assembler will check the variable L% to decide if it can deposit information
- at the current address (P% or O% depending on OPT as usual) (Note that DIM
- P% 1,L% -1 will assign L% a word address (which DIM likes returning) and so
- can take a full word of assembly).
-
- (11) More exported routines from CALL
-
- The value in r14 can be returned to with MOV PC,R14 but it also points to an
- array of useful values:
-
- B CALL2REAL ;0th entry in table is return address
- ;the following values are words containing an offset from ARGP (R8)
- ;word aligned 256 bytes
- & STRACC ;string accumulator
- ;word aligned words offset from ARGP
- & PAGE ;current program PAGE
- & TOP ;current program TOP
- & LOMEM ;current variable start
- & HIMEM ;current stack end
- & MEMLIMIT ;limit of available memory
- & FSA ;free space start (high water mark/FD stack limit)
- & TALLY ;value of COUNT
- & TIMEOF ;offset from TIME readable by OSWORD
- & ESCWORD ;exception flag word (contains escflg, trcflg)
- & WIDTHLOC ;value of WIDTH-1
- ;internal BASIC routines
- B VARIND ;get value of lv
- B STOREA ;store value into lv
- B STSTORE ;store string into type 128 strings
- B LVBLNK ;convert string "variable name" to lv address and type
- B CREATE ;create new variable
- B EXPR ;use expression analyser on string
- B MATCH ;lexical analyse source string to destination string
- B TOKENADDR ;pointer to string for particular token
- & 0 ;stop point for ****** Minerva programs
- ;new on BASIC V 1.03
- & 9 ;length of extensions
- B FSTA ;store fp in r0-r3 as 5 bytes at r9
- B FLDA :load fp from r9 as 5 bytes into r0-r3
- B FADD ;add fp in r0-r3 to 5 bytes at r9, result in r0-r3
- B FSUB ;subtract fp in r0-r3 from 5 bytes at r9, result in r0-r3
- B FMUL ;multiply fp in r0-r3 by 5 bytes at r9, result in r0-r3
- B FDIV ;divide fp in 5 bytes at r9 by r0-r3, result in r0-r3
- B FLOAT ;float an integer in r0 to an fp in r0-r3
- B FIX ;fix an fp in r0-r3 to an integer in r0
- B FSQRT ;square root of r0-r3
-
- Note that the list is held in two different forms: the first section is
- exactly like BASIC 1.02: a list terminated by zero. The list could not be
- simply extended because of some unfortunate assumptions bound into poorly
- written application programs, so a second list has been tacked on the end.
- A client can check the number of extensions field (i.e. the field after the
- zero) and it will be 0 or negative if there aren't any.
-
- The pointer TIMEOF is particularly interesting. On Arthur this location
- holds a meaningless value; on other systems it holds the offset which should
- be subtracted from the time read from the system if one wishes to agree
- with the value given by PRINT TIME. However the next three words offset from
- the argument register after TIMEOF (i.e. [R8,TIMEOF+4] etc.) contain:
-
- LOCALARLIST: a pointer to a list of local arrays.
- INSTALLLIST: a pointer to the list of installed libraries.
- LIBRARYLIST: a pointer to the list of libraries.
-
- The local array list is not going to be much use, but the ability to scan the
- libraries allows (say) find commands to be installed which can find a
- procedure whereever it is. The list consists of a pointer (0 is the end of
- the list) to a word (which is the next pointer) and a BASIC program in
- internal form immediately following the word. The list is organised in the
- search order.
-
- The internal routines are only guarenteed to work in processor user mode.
- The following functions are provided:
-
- VARIND: entry with r0=address of lv, r9=type of lv, r12=LINE.
- Returns with r0..r3 as the value, r9 the type of the value as follows:
-
- r9 type where
- 0 string in STRACC, r2 points to end (r2-STRACC is length)
- &40000000 integer in r0
- &80000000 float in r0..r3
-
- Uses no other registers (including stack). Possible error if asked to take
- value of an array fred(): will need r12 valid for this error to be reported
- correctly.
-
- STOREA: entry with r0..r3 value, r9=type of value and r4=address of lv,
- r5=type of lv, r8=ARGP, r12=LINE (for errors) and r13=SP (for out of store
- chcek on string allocation). Will convert between various formats e.g.
- integer and float or produce an error if conversion is impossible.
- Returns with r0..r7 destroyed. Stack not used.
-
- STSTORE: entry with r4=address of lv, r2=length (address of end), r3=address
- of start, r8=ARGP, r12=LINE (for out of store error) and r13=SP (for out of
- store check). The string must start on a word boundary, the length must be
- 255 or less.
- Uses r0, r1, r5, r6, r7. Preserves input registers. Stack not used.
-
- LVBLNK: entry with r11 pointing to start of string, r8=ARGP, r12=LINE (many
- errors possible e.g. subscript error in array) and r13=stack (will be used
- for evaluation of subscript list: calls EXPR). The string will be processed
- to read one variable name and provide an address and type which can be given
- to VARIND.
- Returns with NE status if a variable has been found. Address in r0, type (see
- above) in r9. If there is an EQ status then if the carry is set it cannot
- possibly be a variable else if the carry is clear it could be, but isn't
- known to the interpreter (and registers are set to values for CREATE).
- Uses all registers.
-
- CREATE: create a variable. Input is the failure of LVBLNK to find something.
- Thus we have r10=first char of item, r3=second char of item or 0, r4 and r11
- pointers to start and end of other chars, r8=ARGP, r12=LINE, r13=STACK, r9
- contains the number of zero bytes on the end. It is recommended that CREATE
- is called immediately after a failed LVBLNK only.
- Uses all registers. Return parameters as LVBLNK.
-
- The LVBLNK and CREATE routines can be combined together to provide a routine
- which checks for a variable to assign to and creates it if necessary:
-
- SAFELV STMFD SP!,{R14}
- BL LVBLNK
- LDMNEFD SP!,{PC}
- LDMCSFD SP!,{PC}
- BL CREATE
- LDMFD SP!,{PC}
-
- EXPR: entry with r11 pointing to start of string, r8=ARGP, r12=LINE, r13=STACK.
- EXPR stops after reading one expression (like those in the PRINT statement).
- Uses all registers. The value is returned like VARIND. If status EQ it read a
- string, if status NE and plus it read an integer word (in r0) if status NE
- and minus it read a floating point value (in r0..r3). r9 contains the type:
- the status can be recreated by TEQ r9,#0. r10 contains the delimiting
- character, r11 points to the one after.
-
- MATCH: entry with r1=source string (terminated by ASCII CR=13),
- r2=destination string, r3=MODE, r4=CONSTA, r13=STACK. Note that MATCH does
- not need ARGP or LINE. The MODE value is 0 for LEFT MODE (i.e. before an
- equals sign) and 1 for RIGHT MODE (after an equals sign or in an expression).
- The CONSTA value is 0 for don't pack constants using token &8D, &8D itself
- for pack. Both MODE and CONSTA will be updated during use of the routine
- e.g. GOTO will change CONSTA to &8D to read the constant, PRINT will change
- MODE to 1 to read the expression. Starting values of MODE=0 and CONSTA=0
- will lexcially analyse a statement; MODE=1 and CONSTA=0 an expression;
- MODE=0 and CONSTA=&8D is used to extract line numbers in command mode and
- probably has little use. MODE affects the values assigned to tokens for
- HIMEM etc.
- Uses r0-r5. r1 and r2 are left pointing after the CR codes in the strings.
- r5 contains status about failures to analyse the line correctly: it can be
- used or disregarded: values >= &1000 imply mismatched brackets, bit 8 set
- implies a line number was found that was too large to be put into a &8D
- constant and if r5 AND 255 equals 1 it implies mismatched string quotes.
-
- TOKENADDR: entry with r0 as the token value, r12=pointer to next byte of
- token string. The value in r12 is only used when the address of a two byte
- token is required. No other register are used or required.
- Returns r1 as the pointer to the first character of a string, terminated by a
- value >=&7F (which is the first byte of the token value). r0 is set to the
- address of the start of the token table itself. r12 will have been
- incremented by 1 if a two byte token was used.
-
- FSTA: Saves the five byte form of a floating point number. Entry with r0-r3
- as the floating point value, r9=address of destination. Stack not used. No
- error possible. r2 altered (but this does not affect the fp value of r0-r3).
-
- FLDA: Loads the five byte form of a floating point number. Entry with address
- in r9. Exit with r0-r3 as floating point value. Stack not used. No error
- possible.
-
- FADD: Add floating point value in r0-r3 to five byte form at r9. Result in
- r0-r3. Stack not used. Overflow error possible. Uses r4-r7.
-
- FSUB: Subtract floating point value in r0-r3 from five byte form at r9.
- Result in r0-r3. Stack not used. Overflow error possible. Uses r4-r7.
-
- FMUL: Multiply floating point value in r0-r3 by five byte form at r9. Result
- in r0-r3. Stack not used. Overflow error possible. Uses r4-r7.
-
- FDIV: Divide five byte form at r9 by floating point value in r0-r3. Result
- in r0-r3. Stack not used. Divide by zero and overflow error possible. Uses
- r4-r7.
-
- FLOAT: Float an integer in r0 to a floating point value in r0-r3. Stack not
- used, no error possible. Sets type field in r9 to FLOATING (&80000000).
-
- FIX: Fix a floating point value in r0-r3 to an integer in r0. Stack not used.
- Overflow error possible. Sets type field in r9 to INTEGER (&40000000).
-
- FSQRT: Square root of floating point value in r0-r3 return in r0-r3. Uses
- r4-r7.
-
- (12) Sped up areas
-
- Simple expressions (indeed very complex ones have been slowed down!). SYS
- statement, especially where no results (no TO) are required. String
- allocation (by varying amounts depending on what is happening).
-
- (13) Bugs fixed
-
- 18-Sep-87 division by power of 2 did not check under/overflow.
- 24-Sep-87 LOCAL A()
- 28-Sep-87 A()=const
- 08-Dec-87 LOCAL A():DIM A(1,1) messed stack due to bug in DIM re type (also
- misallocates integer arrays!).
- 04-Jan-88 LINE INPUT had sense of LINE flag wrong - misbehaved for A,B ans.
- 05-Jan-88 HIMEM=HIMEM wouldn't work.
- 08-Feb-88 CREATE was uncallable due to LVBLNK loosing R4.
- 26-Feb-88 STRACC postion changed for Arthur 2.00.
- 29-Feb-88 $A="" check for <&8000.
- 07-Mar-88 50IF<false>THEN50 unescapeable
- 12-May-88 INPUT#,a$ at end of file gives end of file message.
- 23-May-88 ATN of a large power of 2 went wrong.
- 01-Sep-88 WHILE <no sd> failed in TRACE state due to moving LINE in SLOWMUNG
-